package cn.slg.module.system.dal.dataobject.state;

import cn.slg.module.system.dal.dataobject.wujiang.WuJiangDO;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Consumer;

import static cn.slg.module.system.service.pk.utils.Print.percentInstance;
import static cn.slg.module.system.service.pk.utils.Show.*;

@Data
@NoArgsConstructor
// 属性状态
// 状态施加时生效begin()，等到相应回合数结束end()
// 属性状态主要包括三种效果：改变战法发动几率、改变战法造成的伤害、改变受到战法的伤害。
public class PropertyState extends State {

    // 来自不同战法的同种属性状态可以叠加，相同战法的同种属性不能叠加

    // 来自不同战法的同种属性，会刷新，来自同一战法的同种属性状态将会刷新持续回合
    private boolean canRefresh = true;

    private Consumer<WuJiangDO> begin;

    private Consumer<WuJiangDO> end;

    // 来自同一战法的同种属性状态将会刷新持续回合。
    public void refresh(WuJiangDO inflictor, byte continueTimes) {
        this.setInflictor(inflictor);  // 刷新施加者
        this.setRemainTimes(continueTimes);    // 刷新持续时间
        // System.out.println(receiver.getName() + "的【" + stateName + "】" + "状态被刷新，持续时间为" + continueTimes);
    }


    public void begin(WuJiangDO target) {
        begin.accept(target);
        // 该属性状态被添加给 target
        target.getPropertyStates().add(this);
    }

    // 该属性状态终止
    public void end() {
        // 调用终止函数
        end.accept(receiver);
        // 该属性状态结束，移除。
        receiver.getPropertyStates().remove(this);
    }


    public PropertyState(boolean isNegative, String stateName, WuJiangDO inflictor, WuJiangDO receivers, Method skill, String skillName, byte continueTimes, Consumer<WuJiangDO> begin, Consumer<WuJiangDO> end) {
        super(isNegative, stateName, inflictor, receivers, skill, skillName, continueTimes);
        this.begin = begin;
        this.end = end;
    }

    public static boolean canAddState(String stateName, WuJiangDO inflictor, WuJiangDO receiver, Method skill, String skillName, byte continueTimes) {

        // 首先看能否叠加。即武将身上是否已经有相同战法施加的这一相同状态，
        List<PropertyState> propertyStates = receiver.getPropertyStates();

        boolean canAdd = true;      // 默认能够将该属性状态添加到接收者身上

        // 遍历接收者身上的所有 属性状态
        for (PropertyState propertyState : propertyStates) {
            if (skill == propertyState.skill && stateName.equals(propertyState.stateName)) {
                // TODO 如果战法相同，且状态相同，不能叠加，否则都能叠加。
                canAdd = false;

                // TODO 虽然不能叠加，但是能够刷新，这里进行刷新。
                if (propertyState.canRefresh) {
                    WuJiangDO inflictor1 = propertyState.getInflictor();
                    System.out.println(spacing2() + showName(receiver) + "已有来自" + showName(inflictor1) + parcel1(skillName) + "的" + parcel1(stateName) + "效果，无法叠加");
                    // 可以刷新已有的状态
                    propertyState.refresh(inflictor, continueTimes);
                }
            }
        }
        return canAdd;
    }

    public static void addState(boolean isNegative, String stateName, WuJiangDO inflictor, WuJiangDO receiver, Method skill, String skillName, byte continueTimes,
                                Consumer<WuJiangDO> begin, Consumer<WuJiangDO> end) {
        // 创建该属性状态
        PropertyState propertyState = new PropertyState(isNegative, stateName, inflictor, receiver, skill, skillName, continueTimes, begin, end);
        // 属性状态生效
        propertyState.begin(receiver);
    }
}
